using micromsgBackground;
using MicroMsgBackground.Common.Utils;
using MicroMsgBackground.Manager;
using MicroMsgBackground.Protocol;
using System;
using System.Collections.Generic;
namespace MicroMsgBackground.Scene
{
	public class NetSceneNewSync : NetSceneBaseEx<NewSyncRequest, NewSyncResponse, NewSyncRequest.Builder>
	{
		public delegate bool ProcessCmdItemDelegate(NewSyncRequest request, NewSyncResponse response, List<object> cmdObjectList);
		private const string TAG = "NetSceneNewSync";
		public const int MM_NEWSYNC_PROFILE = 1;
		public const int MM_NEWSYNC_MSG = 2;
		public const int MM_NEWSYNC_WXCONTACT = 4;
		public const int MM_NEWSYNC_PMCONTACT = 8;
		public const int MM_NEWSYNC_QQCONTACT = 16;
		public const int MM_NEWSYNC_BOTTLECONTACT = 64;
		public const int MM_NEWSYNC_DEFAULT_SELECTOR = 7;
		public const int MM_NEWSYNC_ALL_SELECTOR = 31;
		public const int MM_NEWSYNC_ALBUMSYNCKEY = 128;
		public const int MM_NEWSYNC_SNSSYNCKEY = 256;
		private const int MAX_CONTINUE_SYNC_COUNT = 50;
		public const int MAX_RETRY_COUNT = 1;
		public const int TIMER_INTERVAL = 30000;
		private int mContiuneSyncCount;
		private static int mSyncCount;
		private static int mNotifyCount;
		private int mSyncStatus;
		private int mSelector = 7;
		public static byte[] mBytesSyncKeyBuf;
		private static bool mIsAppActive;
		public static bool isEnable;
		public static bool mHasNewMsg;
		public bool doSceneBackground(int selector, syncScene scene = syncScene.MM_NEWSYNC_SCENE_OTHER)
		{
			if (!AccountMgr.hasValidAccount())
			{
				Log.smethod_1("NetSceneNewSync", "get current account failed.");
				return false;
			}
			NetSceneNewSync.mBytesSyncKeyBuf = AccountMgr.getCurAccount().bytesSyncKeyBuf;
			Log.smethod_4("NetSceneNewSync", string.Concat(new object[]
			{
				"doScene: Sync now, selector:",
				selector,
				" mNotifyCount = ",
				NetSceneNewSync.mNotifyCount
			}));
			this.mSelector |= selector;
			this.mSelector &= -65;
			if (this.mSyncStatus == 1)
			{
				Log.smethod_4("NetSceneNewSync", "is doing sync now,return this request");
				return true;
			}
			this.mSyncStatus = 1;
			NetSceneNewSync.mHasNewMsg = false;
			if (NetSceneNewSync.mNotifyCount > 0)
			{
				NetSceneNewSync.mNotifyCount--;
			}
			NetSceneSyncResult netSceneSyncResult = new NetSceneSyncResult();
			netSceneSyncResult.retCode = RetConst.MM_OK;
			netSceneSyncResult.syncStatus = SyncStatus.syncBegin;
			netSceneSyncResult.syncCount = NetSceneNewSync.mSyncCount;
			netSceneSyncResult.isAppActive = NetSceneNewSync.mIsAppActive;
			Log.smethod_5("NetSceneNewSync", "do sync post begin");
			if (NetSceneNewSync.mSyncCount == 0)
			{
				scene = syncScene.MM_NEWSYNC_SCENE_PROCESSSTART;
			}
			this.continueDoScene(this.mSelector, scene);
			return true;
		}
		private bool continueDoScene(int selector, syncScene scene)
		{
			base.beginBuilder();
			this.mBuilder.Selector = (uint)selector;
			this.mBuilder.Oplog = CmdList.CreateBuilder().SetCount(0u).Build();
			this.mBuilder.KeyBuf = Util.toSKBuffer(NetSceneNewSync.mBytesSyncKeyBuf);
			this.mBuilder.Scene = (uint)scene;
			this.mSessionPack.mCmdID = 26;
			base.endBuilder();
			if (this.mContiuneSyncCount < 50)
			{
				this.mContiuneSyncCount++;
			}
			else
			{
				Log.smethod_5("NetSceneNewSync", "mSyncCount exceed the maximum");
			}
			return true;
		}
		private bool isEmptySync(NewSyncResponse response)
		{
			return NetSceneNewSync.mSyncCount == 1 && !this.canContinue(response) && response.CmdList.Count == 0u;
		}
		protected override void onSuccess(NewSyncRequest request, NewSyncResponse response)
		{
			int ret = response.Ret;
			if (ret != 0)
			{
				Log.smethod_1("NetSceneNewSync", "doScene: Sync failed!" + ret);
				this.mSyncStatus = 2;
				NetSceneSyncResult netSceneSyncResult = new NetSceneSyncResult();
				netSceneSyncResult.retCode = (RetConst)response.Ret;
				netSceneSyncResult.syncStatus = SyncStatus.syncErr;
				netSceneSyncResult.syncCount = NetSceneNewSync.mSyncCount;
				netSceneSyncResult.isAppActive = NetSceneNewSync.mIsAppActive;
				NetSceneNewSync.mIsAppActive = false;
				return;
			}
			Log.smethod_4("NetSceneNewSync", string.Concat(new object[]
			{
				"doScene: Sync success, continueFlag = ",
				response.ContinueFlag,
				" response.CmdList.Count = ",
				response.CmdList.Count
			}));
			List<object> cmdObjectList = null;
			this.ProcessCmdItem(request, response, cmdObjectList);
			if (this.isEmptySync(response) && RecycleMgr.needRecyle())
			{
				Log.smethod_5("NetSceneNewSync", "doFileRecycle in EmptySyn");
				RecycleMgr.doFileRecycle();
				Log.LogToFile();
			}
		}
		private bool ProcessCmdItem(NewSyncRequest request, NewSyncResponse response, List<object> cmdObjectList)
		{
			Log.smethod_6("NetSceneNewSync", "ProcessCmdItem in");
			if (!this.saveInfo(request, response))
			{
				Log.smethod_1("NetSceneNewSync", "SaveUserInfo failed");
			}
			if (this.canContinue(response))
			{
				Log.smethod_4("NetSceneNewSync", "doScene: Sync NewSyncContinue");
				this.continueDoScene(this.mSelector, syncScene.MM_NEWSYNC_SCENE_CONTINUEFLAG);
				return true;
			}
			Log.smethod_4("NetSceneNewSync", string.Concat(new object[]
			{
				"doScene: Sync finished mSyncCount = ",
				NetSceneNewSync.mSyncCount,
				" mNotifyCount = ",
				NetSceneNewSync.mNotifyCount
			}));
			this.mSyncStatus = 0;
			NetSceneSyncResult netSceneSyncResult = new NetSceneSyncResult();
			netSceneSyncResult.retCode = (RetConst)response.Ret;
			netSceneSyncResult.syncStatus = SyncStatus.syncEnd;
			netSceneSyncResult.syncCount = NetSceneNewSync.mSyncCount;
			netSceneSyncResult.isAppActive = NetSceneNewSync.mIsAppActive;
			netSceneSyncResult.hasNewMsg = NetSceneNewSync.mHasNewMsg;
			NetSceneNewSync.mIsAppActive = false;
			this.resetFlag();
			NetSceneNewSync.mSyncCount++;
			NetSceneNewSync.mNotifyCount = 0;
			return true;
		}
		private void resetFlag()
		{
			this.mContiuneSyncCount = 0;
			this.mSelector = 7;
		}
		protected override void onFailed(NewSyncRequest request, NewSyncResponse response)
		{
			base.getLastError();
			this.resetFlag();
			this.mSyncStatus = 2;
			NetSceneSyncResult netSceneSyncResult = new NetSceneSyncResult();
			netSceneSyncResult.retCode = RetConst.MM_ERR_CLIENT;
			netSceneSyncResult.syncStatus = SyncStatus.syncErr;
			netSceneSyncResult.syncCount = NetSceneNewSync.mSyncCount;
			netSceneSyncResult.isAppActive = NetSceneNewSync.mIsAppActive;
			NetSceneNewSync.mIsAppActive = false;
		}
		private bool canContinue(NewSyncResponse resp)
		{
			return ((ulong)resp.ContinueFlag & (ulong)((long)this.mSelector)) != 0uL && this.mContiuneSyncCount < 50;
		}
		private bool saveInfo(NewSyncRequest request, NewSyncResponse response)
		{
			if (request == null || response == null)
			{
				Log.smethod_1("NetSceneNewSync", "invalid NewSyncReq or NewSyncResp");
				return false;
			}
			NetSceneNewSync.mBytesSyncKeyBuf = NetSceneNewSync.mergeKeyBuf(request.KeyBuf.Buffer.ToByteArray(), response.KeyBuf.Buffer.ToByteArray());
			Log.smethod_6("NetSceneNewSync", "request.KeyBuf  =" + Util.toHexString(request.KeyBuf.Buffer.ToByteArray()));
			Log.smethod_6("NetSceneNewSync", "response.KeyBuf =" + Util.toHexString(response.KeyBuf.Buffer.ToByteArray()));
			Log.smethod_6("NetSceneNewSync", "merg KeyBuf     =" + Util.toHexString(NetSceneNewSync.mBytesSyncKeyBuf));
			AccountBackground curAccount = AccountMgr.getCurAccount();
			curAccount.bytesSyncKeyBuf = NetSceneNewSync.mBytesSyncKeyBuf;
			if (response.CmdList.Count == 0u)
			{
				return true;
			}
			AccountMgr.saveSyncData(request, response, NetSceneNewSync.mBytesSyncKeyBuf);
			AccountMgr.saveBackgroundAccout(curAccount);
			Log.smethod_5("NetSceneNewSync", "newsync doscene save bytesSyncKeyBuf success");
			return true;
		}
		public static byte[] mergeKeyBuf(byte[] oldbuf, byte[] newbuf)
		{
			if (oldbuf == null || oldbuf.Length == 0)
			{
				return newbuf;
			}
			if (newbuf != null && newbuf.Length != 0)
			{
				SyncKey syncKey = null;
				byte[] result;
				try
				{
					syncKey = SyncKey.ParseFrom(oldbuf);
				}
				catch (Exception ex)
				{
					Log.smethod_1("NetSceneNewSync", "synckey oldbuf is invalid" + ex.get_Message());
					result = newbuf;
					return result;
				}
				SyncKey syncKey2 = null;
				try
				{
					syncKey2 = SyncKey.ParseFrom(newbuf);
					goto IL_7D;
				}
				catch (Exception ex2)
				{
					Log.smethod_1("NetSceneNewSync", "synckey newbuf is invalid" + ex2.get_Message());
					result = oldbuf;
				}
				return result;
				IL_7D:
				IList<KeyVal> keyList = syncKey.KeyList;
				IList<KeyVal> keyList2 = syncKey2.KeyList;
				Dictionary<uint, uint> dictionary = new Dictionary<uint, uint>();
				for (int i = 0; i < keyList.get_Count(); i++)
				{
					if (!dictionary.ContainsKey(keyList.get_Item(i).Key))
					{
						dictionary.Add(keyList.get_Item(i).Key, keyList.get_Item(i).Val);
					}
				}
				for (int j = 0; j < keyList2.get_Count(); j++)
				{
					if (dictionary.ContainsKey(keyList2.get_Item(j).Key))
					{
						if (keyList2.get_Item(j).Val > dictionary.get_Item(keyList2.get_Item(j).Key))
						{
							dictionary.set_Item(keyList2.get_Item(j).Key, keyList2.get_Item(j).Val);
						}
					}
					else
					{
						dictionary.Add(keyList2.get_Item(j).Key, keyList2.get_Item(j).Val);
					}
				}
				SyncKey syncKey3 = SyncKey.DefaultInstance;
				SyncKey.Builder builder = new SyncKey.Builder().SetKeyNum((uint)dictionary.get_Count());
				using (Dictionary<uint, uint>.Enumerator enumerator = dictionary.GetEnumerator())
				{
					while (enumerator.MoveNext())
					{
						KeyValuePair<uint, uint> current = enumerator.get_Current();
						KeyVal keyVal = KeyVal.CreateBuilder().SetKey(current.get_Key()).SetVal(current.get_Value()).Build();
						builder.KeyList.Add(keyVal);
					}
				}
				syncKey3 = builder.Build();
				return syncKey3.ToByteArray();
			}
			return oldbuf;
		}
	}
}
